#include "cmsis_os.h"
#include "main.h"
#include "messager.h"
#include "product_info.h"

#ifdef CFG_SUPPORT_RTC
#include "rtc.h"
#endif

#ifndef SIMULATOR
#include "stm32l4xx_hal.h"
#endif

// ##
#define LOG_TAG     "router"
#include "ulog.h"

// ##
static uint32_t list_mail[] =
{
    MSG_RTC_SET_TIME,
    MSG_RTC_ALARM,
    MSG_BTN_EVENT,
};

#define MAIL_LIST_DEPTH (sizeof(list_mail) / sizeof(uint32_t))

// ##
static mMessager_t mail_box;

// ##
static uint32_t stack_last = 0;
static uint32_t stack_cur = 0;

// ##
void thread_router(void const *argument)
{
    // ##
    msg_t msg;
    uint8_t content[256];
    uint32_t len = 0;
    rtc_struct_t rtc_struct;

    // ##
    mail_box = messager_create(MAIL_LIST_DEPTH);

    messager_register(mail_box, &list_mail[0], MAIL_LIST_DEPTH);

    // ##
    rtc_struct.hour = BUILT_HOUR;
    rtc_struct.minutes = BUILT_MINUTE;
    rtc_struct.seconds = BUILT_SECOND;
    rtc_struct.year = BUILT_YEAR;
    rtc_struct.month = BUILT_MONTH;
    rtc_struct.day = BUILT_DAY;

    messager_mail(MSG_RTC_SET_TIME, &rtc_struct, sizeof(rtc_struct_t));

#ifdef CFG_SUPPORT_RTC
    rtc_init();
#endif

    // ##
    log_info("%s starts to run\r\n", __func__);

    // ##
    for (;;)
    {
        if (messager_recv(mail_box, &msg, content, &len, sizeof(content)) != RESULT_ERR)
        {
            switch (msg)
            {
                case MSG_RTC_ALARM:
                {
                    rtc_struct_t time;
                    rtc_time_get(&time);
                    log_info("rtc time  : %04d-%02d-%02d, %02d:%02d:%02d, %d\r\n",
                                        time.year,
                                        time.month + 1,
                                        time.day,
                                        time.hour,
                                        time.minutes,
                                        time.seconds,
                                        time.week);
                    break;
                }
                case MSG_RTC_SET_TIME:
                {
                    // ##
                    rtc_struct_t *new_time = (rtc_struct_t *)&content[0];

                    // ##
                    rtc_time_set(new_time);

                    // ##
                    rtc_alarm_set(new_time);

                    // ##
                    log_info("MSG_RTC_SET_TIME : %02d:%02d:%02d, %d, %02d-%02d-%04d\r\n",
                            new_time->hour, new_time->minutes,
                            new_time->seconds, new_time->week,
                            new_time->month, new_time->day, new_time->year + 2000);

                    break;
                }
                default:
                {
                    log_info("msg %d is not listed, please check it.\r\n", msg);
                    break;
                }
            }

            // ##
            stack_cur =  uxTaskGetStackHighWaterMark(osThreadGetId());

            if (stack_cur != stack_last)
            {
                stack_last = stack_cur;

                log_info("[%s] %ld bytes left in stack %ld bytes\r\n", osThreadGetName(osThreadGetId()), stack_cur * sizeof(StackType_t), THREAD_ROUTER_STACK_DEPTH * sizeof(StackType_t));
            }
        }
        else
        {
            log_error("failed to receive from mail_box.\r\n");
        }
    }
}
